import com.young.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class Main {

    public void testReflect() {
        Class clz = null;
        Student st = null;
        //获取JVM Class实例
        //Class clzz = Student.class;
        //Student st = new Student();
        //Class clz = st.getClass();
        try {
            clz = Class.forName("com.young.Student");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //创建Student类对象
        //方法一
        /*try {
            clz.newInstance();  //只能调用默认构造函数创建对象
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }*/

        //方法二，可传参
        try {
            //注意getConstructor()中的参数，可指定返回哪个getConstructor
            Constructor cons = clz.getConstructor(new Class[]{String.class,int.class});
            st = (Student)cons.newInstance("sdf",20);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //获取成员变量
        try {
            //私有成员变量必须用getDeclaredField才能获取
            Field field = clz.getDeclaredField("age");
            //field.setAccessible(true);
            System.out.println(field);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        Field[] fields = clz.getFields();
        System.out.println("all fields:");
        Arrays.asList(fields).forEach(System.out::println); // name & age

        try {
            System.out.println("call methods:");
            //注意getMethod()的第二个参数，在有重载方法时将决定调用哪个
            Method setNameMethod = clz.getMethod("setName",String.class);
            setNameMethod.invoke(st,"小明");
            //私有方法需要用getDeclaredMethod()才能获取
            Method printNmaeMethod = clz.getDeclaredMethod("printName");
            //调用私有方法前必须设置accessible为true
            printNmaeMethod.setAccessible(true);
            printNmaeMethod.invoke(st);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    public static void main(String[] args) {
        Main app = new Main();
        app.testReflect();
    }
}
